Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accept label value as regexp #171

Merged
merged 1 commit into from
Jan 2, 2024

Conversation

sathieu
Copy link
Contributor

@sathieu sathieu commented Dec 7, 2023

Fixes: #82

Copy link
Contributor

@simonpasquier simonpasquier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling this! Reading the issue, I have the impression that supporting regexp label values only for --label-value was enough (e.g. only for static values). Do you have a use case for supporting the same for --query-param and --header-name?

Given the security implications (e.g. it's easy to get the regexp wrong and expose too many metrics by accident), I'd be more inclined to limit the scope for now.

README.md Outdated Show resolved Hide resolved
main.go Outdated Show resolved Hide resolved
@sathieu
Copy link
Contributor Author

sathieu commented Dec 7, 2023

Thanks for tackling this! Reading the issue, I have the impression that supporting regexp label values only for --label-value was enough (e.g. only for static values). Do you have a use case for supporting the same for --query-param and --header-name?

Yes.

Here is my usecase : I have multiple (soft-)tenants in a Kubernetes cluster. Each can include a list of namespace ([app1, app2]) or a list of namespace regexps ([tenant1-.+]). For the first case, Grafana is not able to pass the same header multiple times (see grafana/grafana-plugin-sdk-go#829), so here regexp support is a workaround. For the second case (less common), I really need regexp support.

Alternatively, a new tenant label could have been set at scrapping time. This is waiting for Scrape classes support in Prometheus Operator.

Given the security implications (e.g. it's easy to get the regexp wrong and expose too many metrics by accident), I'd be more inclined to limit the scope for now.

I understand. But I need it 😉 . Maybe add a warning in the docs?

@simonpasquier
Copy link
Contributor

Thanks for the details, it helps a lot! I could agree to the feature being marked as experimental with an very clear warning in the CLI help + README.md file.

The proxy needs also to validate that the regexp is valid. Also what should the proxy's response when it gets several label values? My gut feeling is that it should fail.

@sathieu
Copy link
Contributor Author

sathieu commented Dec 11, 2023

Thanks @simonpasquier I've rebased, added warnings in README, added checks for invalid regex and multiple values.

Back to you 🏓 !

README.md Outdated Show resolved Hide resolved
README.md Outdated
Comment on lines 151 to 152
-header-name X-Namespace \
-label namespace \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(suggestion) I'd use a static label value to make it more "visible".

Suggested change
-header-name X-Namespace \
-label namespace \
-label-value '^foo-.+$' \
-label namespace \

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we shouldn't anchor the regexp by default (like Prometheus does for relabelings)? It would at least prevent too-permissive configurations.
It'd also be good to require that the compiled regex doesn't match the empty string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we shouldn't anchor the regexp by default (like Prometheus does for relabelings)? It would at least prevent too-permissive configurations.

Prometheus anchors already.

It'd also be good to require that the compiled regex doesn't match the empty string.

Good idea.

main.go Outdated Show resolved Hide resolved
main.go Show resolved Hide resolved
injectproxy/routes.go Show resolved Hide resolved
@sathieu sathieu force-pushed the label_regexp branch 3 times, most recently from 423ccc9 to 372db15 Compare December 11, 2023 17:01
@sathieu
Copy link
Contributor Author

sathieu commented Dec 11, 2023

@simonpasquier I've merged your suggestions, added tests for regexp matching empty strings, and added tests early when using -label-value.

main.go Show resolved Hide resolved
injectproxy/silences_test.go Show resolved Hide resolved
injectproxy/routes_test.go Outdated Show resolved Hide resolved
injectproxy/routes_test.go Outdated Show resolved Hide resolved
injectproxy/routes_test.go Outdated Show resolved Hide resolved
@sathieu sathieu force-pushed the label_regexp branch 2 times, most recently from 646a9f5 to 791471e Compare December 12, 2023 15:33
@sathieu
Copy link
Contributor Author

sathieu commented Dec 12, 2023

@simonpasquier Thanks for your review. I've merged your suggestions, and silence API is now returning 501 Not Implemented when regex match is enabled. I'll try to add support for multiple values in silences in a future PR.

Back to you 🏸 !

Copy link
Contributor

@simonpasquier simonpasquier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one last comment...

mux.Handle("/api/v2/silences", r.el.ExtractLabel(
enforceMethods(
assertSingleLabelValue(r.silences),
if opt.regexMatch {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(suggestion) to avoid duplicating the mux.Handle() calls, we might do something like this:

errs.Add(
    mux.Handle("/api/v2/silences", r.errorIfRegexpMatch(
        r.el.ExtractLabel(...

[...]

 func (r *routes) errorIfRegexpMatch(next http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, req *http.Request) {
        if r.regexMatch {
            prometheusAPIError(w, "support for regex match not implemented", http.StatusNotImplemented)
            return
        }

        return next(w, req)
    }
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done @simonpasquier. Back to you ⚾ !

Copy link
Contributor

@simonpasquier simonpasquier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! 👍 for me.
@squat do you have any concern with this addition? From my side, the warning in the README.md is clear enough that users know about the potential issues if they mess up with their regexp.

README.md Outdated Show resolved Hide resolved
@simonpasquier simonpasquier merged commit f37112a into prometheus-community:main Jan 2, 2024
4 checks passed
simonpasquier added a commit to simonpasquier/prom-label-proxy that referenced this pull request Jun 7, 2024
PR prometheus-community#171 implemented support for regex label values but only for the
query endpoints. This change adds support for all other Prometheus API
endpoints.

Signed-off-by: Simon Pasquier <[email protected]>
simonpasquier added a commit to simonpasquier/prom-label-proxy that referenced this pull request Jun 7, 2024
PR prometheus-community#171 implemented support for regex label values but only for the
query endpoints. This change adds support for all other Prometheus API
endpoints.

Signed-off-by: Simon Pasquier <[email protected]>
simonpasquier added a commit to simonpasquier/prom-label-proxy that referenced this pull request Jun 12, 2024
PR prometheus-community#171 implemented support for regex label values but only for the
query endpoints. This change adds support for all other Prometheus API
endpoints.

Signed-off-by: Simon Pasquier <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Specify label value in prom-label-proxy config / Wildcards in Labels
2 participants